package it.milanoeasy.utils;

import java.util.Random;

import javax.crypto.*;
import javax.crypto.spec.*;
import org.apache.commons.codec.binary.Hex;

/**
 * 
 */

public class MECrypt {	

	private Cipher ecipher;
	private Cipher dcipher;
	private String algorithm = "DESede";
	private String transformation = "DESede/CBC/PKCS5Padding";
	private String keyPhrase = "912345678901232567890123"; //your keyphrase 24 bit
	private SecretKey key;
	private IvParameterSpec iv;
	private static MECrypt cryptoUtil;
	private String ENCODING = "UTF-8";

	private MECrypt() throws Exception {
		DESedeKeySpec keySpec = new DESedeKeySpec(keyPhrase.getBytes());
		key = SecretKeyFactory.getInstance(algorithm).generateSecret(keySpec);
		iv = new IvParameterSpec(new byte[8]);
		ecipher = Cipher.getInstance(transformation);
		dcipher = Cipher.getInstance(transformation);
		ecipher.init(Cipher.ENCRYPT_MODE, key, iv);
		dcipher.init(Cipher.DECRYPT_MODE, key, iv);
	}

	static public String randomString(final int length) {
	    Random r = new Random(); // perhaps make it a class variable so you don't make a new one every time
	    StringBuilder sb = new StringBuilder();
	    for(int i = 0; i < length; i++) {
	        char c = (char)(r.nextInt((int)(Character.MAX_VALUE)));
	        sb.append(c);
	    }
	    return sb.toString();
	} 
	
	public String encrypt(String str) throws Exception {

		byte[] utf8 = str.getBytes(ENCODING);    
		byte[] enc = ecipher.doFinal(utf8);                
		System.out.println("number of bites: " + enc.length);    
		return Hex.encodeHexString(enc);
	}

	public String decrypt(String str) throws Exception {
		byte [] dec=Hex.decodeHex(str.toCharArray());    		            
		byte[] utf8 = dcipher.doFinal(dec);
		return new String(utf8);            
	}

	public static MECrypt getInstance() throws Exception {
		if (cryptoUtil == null) {
			cryptoUtil = new MECrypt();
		}

		return cryptoUtil;
	}

	public static String normalize(String in,int len,boolean right){
		String pad="";
		for (int i=0;i<len;i++){
			pad+="0";
		}
		
		if (right){
			in=in.concat(pad);
			in=in.substring(0,len);
		} else {
			in=pad.concat(in);
			in=in.substring(in.length()-len,in.length());
		}
		
		return in;
	} 
	
	

	public static String getClientId(String plainString){    	
		MECrypt test;
		String cryptText=null;
		try {
			test = MECrypt.getInstance();
			cryptText = test.encrypt(plainString);
		} catch (Exception e) {			
			e.printStackTrace();
		}

		return cryptText;
	}


	public static String verifyClientId(String encypheredText){ 
		if (encypheredText!=null){
			MECrypt test=null;
			try {
				test = MECrypt.getInstance();
			} catch (Exception e1) {
				System.err.println("Error in decrypting (singleton): "+e1.getMessage());			}
			String plainText2=null;
			try {
				plainText2=test.decrypt(encypheredText);
			} catch (Exception e) {				
				System.err.println("Error in decrypting: "+e.getMessage());
			}
			//return plainText.equalsIgnoreCase(plainText2);
			return plainText2;
		} else {
			return null;
		}
	}

	public static void main(String[] args) throws Exception  {
		MECrypt test = MECrypt.getInstance();        
		String originalText = "Abcdefgh";        
		System.out.println("originalText: " + originalText);        
		String cryptText = test.encrypt(originalText);        
		System.out.println("cryptText: " + cryptText);        
		System.out.println("cryptText.length: " + cryptText.length());
		System.out.println("cryptText.getBytes().length: " + cryptText.getBytes().length);        
		System.out.println("decote text: " + test.decrypt(cryptText));

	}	
}

